package org.webrtc.mqttclientsample;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.concurrent.Callable;

import org.java_websocket.handshake.ServerHandshake;
import org.json.JSONException;
import org.json.JSONObject;
 
import org.webrtc.ui.VideoUI;

import com.bieyang.anjia.ui.activity.App;
import com.bieyang.anjia.utils.ApplicationUtils;
import com.bieyang.anjia.utils.SubUtils;

import de.greenrobot.event.EventBus;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class MessageService extends Service implements SocketStateCallBack {

	public static final String ACTION_LOGIN = "login";
	public static final String ACTION_RECONNECT = "reconnect";
	public static final String TAG = "MessageService";
	private ZZClient mClient;
	public static String mUid;
	private IBinder binder;

	private static final long KEEP_ALIVE_INTERVAL = 1000 * 60 * 28;

	// Retry intervals, when the connection is lost.
	private static final long INITIAL_RETRY_INTERVAL = 1000 * 10;
	private static final long MAXIMUM_RETRY_INTERVAL = 1000 * 30 * 1;

	// Preferences instance
	private SharedPreferences mPrefs;
	// We store in the preferences, whether or not the service has been started
	public static final String PREF_STARTED = "isStarted";
	// We also store the deviceID (target)
	public static final String PREF_DEVICE_ID = "deviceID";
	// We store the last retry interval
	public static final String PREF_RETRY = "retryInterval";

	private ConnectivityManager mConnMan;

	private long mStartTime;

	public static Context mContext;

	// *******rtc reconnect********
	public boolean rtcRun = true;
	public int threadnum=0;

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return binder;
	}

	private class SocketClientImpl extends Binder implements ISocketClient {

		@Override
		public void sendTextMessage(String to, String text) {

			if (mClient.isOpen()) // if is logining 如果是登陆状态
			{
				LogUtis.log("sendTextMessage:" + text);
				mClient.sendTextMessage(to, text);
			}

		}

		@Override
		public boolean isOpen() {
			// TODO Auto-generated method stub
			return mClient.isOpen();
		}

		@Override
		public void sendPhoneMessage(String to, String text) {
			if (null == mClient) {
				return;
			}
			if (mClient.isOpen()) {
				mClient.sendPhoneMessage(to, text);
			}

		}

	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		LogUtis.log("onCreate:");

		binder = new SocketClientImpl();
		mPrefs = getSharedPreferences(TAG, MODE_PRIVATE);
		mConnMan = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
		startKeepAliveProcess(); //new启动重连线程
	}

	private void init() {
		try {
			mClient = new ZZClient(new URI(ZZConfig.mWebSocketUrl
					+ MessageService.mUid), MessageService.mUid);

		} catch (URISyntaxException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		mClient.setSocketCallBack(this);
		mStartTime = System.currentTimeMillis();

	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {

		if (intent != null) {
			String action = intent.getAction();
			LogUtis.log("onStartCommand:" + action);
			if (ACTION_LOGIN.equals(action)) {
				if (mClient == null || !mClient.isOpen()) {
					doConnect();
				}
			} else if (intent.getAction().equals(ACTION_RECONNECT) == true) {
				if (isNetworkAvailable()) {
					doConnect();
				}
			}
		}
		
		
		return super.onStartCommand(intent, flags, startId);
	}

	// Check if we are online
	private boolean isNetworkAvailable() {
		// NetworkInfo info = mConnMan.getActiveNetworkInfo();
		// if (info == null) {
		// return false;
		// }
		// return info.isConnected();
		return true;
	}

	private synchronized void doConnect() {
		init();
		LogUtis.log("doConnect>>>>>>>>>>>>>>>>>>>");

		new CallableTask<Boolean>(new Callable<Boolean>() {

			@Override
			public Boolean call() throws Exception {
				boolean ret = false;
				try {
					ret = mClient.connectBlocking();
				} catch (Exception e) {
					// TODO: handle exception
				}

				return ret;
			}
		}, new TaskCallback<Boolean>() {

			@Override
			public void success(Boolean result) {
				// if (result)
				// LogUtis.showTast(getApplicationContext(), "登录成功!");
				// else {
				// LogUtis.showTast(getApplicationContext(), "登录失败!");
				// }
			}

			@Override
			public void error(Exception e) {
				// LogUtis.showTast(getApplicationContext(), "初始化失败!");

			}
		}).execute();
		 
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
	}

	// We schedule a reconnect based on the starttime of the service
	public void scheduleReconnect(long startTime) {
		// the last keep-alive interval
		long interval = mPrefs.getLong(PREF_RETRY, INITIAL_RETRY_INTERVAL);

		// Calculate the elapsed time since the start
		long now = System.currentTimeMillis();
		long elapsed = now - startTime;

		// Set an appropriate interval based on the elapsed time since start
		if (elapsed < interval) {
			interval = Math.min(interval * 4, MAXIMUM_RETRY_INTERVAL);
		} else {
			interval = INITIAL_RETRY_INTERVAL;
		}

		LogUtis.log("Rescheduling connection in " + interval + "ms.");

		// Save the new internval
		mPrefs.edit().putLong(PREF_RETRY, interval).commit();

		// Schedule a reconnect using the alarm manager.
		Intent i = new Intent();
		i.setClass(this, MessageService.class);
		i.setAction(ACTION_RECONNECT);
		PendingIntent pi = PendingIntent.getService(this, 0, i, 0);
		AlarmManager alarmMgr = (AlarmManager) getSystemService(ALARM_SERVICE);
		alarmMgr.set(AlarmManager.RTC_WAKEUP, now + interval, pi);
	}

	public static void startService(Context context, String uid) {
		mContext = context;
		Intent serviceIntent = new Intent(context, MessageService.class);
		mUid = uid;
		serviceIntent.setAction(ACTION_LOGIN);
		context.startService(serviceIntent);

	}

	public void reLogin() {
		// 如果不在登陆状态则重新登陆一次
		if (mClient.isClosed()) {
			MessageService.startService(mContext, mUid);
		}
	}

	@Override
	public void onReceiveMessage(Message message) {

		EventBus.getDefault().post(message);
		switch (message.getType()) {
		case PHONE:
			LogUtis.log("onReceiveMessage:" + message.getContent());
			try {
				JSONObject json = new JSONObject(message.getContent());
				if (json.has("type")) {
					if ("phone".equals(json.getString("type"))) {
						VideoUI.Lauch(getApplicationContext(),
								message.getFrom(), message.getFrom(), true,
								false, true);
					}

				}
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			break;

		default:
			break;
		}

	}

	@Override
	public void onClose(int code, String reason, boolean remote) {
		// TODO Auto-generated method stub
		scheduleReconnect(mStartTime);
		// LogUtis.showTast(this, "连接断开");
	}

	@Override
	public void onOpen(ServerHandshake handshakedata) {
		// TODO Auto-generated method stub
		// LogUtis.showTast(this, "连接成功");
		mStartTime = System.currentTimeMillis();
	}

	@Override
	public void onError(Exception ex) {
		// TODO Auto-generated method stub
		scheduleReconnect(mStartTime);

		// LogUtis.showTast(this, "连接断开:" + ex.getMessage());
	}
	Thread keepAliveThread;
	long lastActive;
	void startKeepAliveProcess() {
		int keepAliveInterval = ZZConfig.AliveInterval;
		if (keepAliveInterval > 0) {
			KeepAliveTask task = new KeepAliveTask(keepAliveInterval);
			this.keepAliveThread = new Thread(task);
			task.setThread(this.keepAliveThread);
			this.keepAliveThread.setDaemon(true);
			this.keepAliveThread.setName("websocket Keep Alive (" + ")");
			this.keepAliveThread.start();
		}
	}

	public class KeepAliveTask implements Runnable {
		private int delay;
		private Thread thread;

		public KeepAliveTask(int paramInt) {
			this.delay = paramInt;
		}

		protected void setThread(Thread thread) {
			this.thread = thread;
		}

		public void run() {
			threadnum++;
			
			// new add -----------------------------
			while (rtcRun) {
				Log.d("rtcconnect", "threadnum:"+threadnum);
				if(null==mClient){
					try {
						mClient = new ZZClient(new URI(ZZConfig.mWebSocketUrl
								+ MessageService.mUid), MessageService.mUid);

					} catch (URISyntaxException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if ((!(mClient.isClosed()))
						&& (mClient.keepAliveThread == this.thread)) {
					synchronized (mClient) {
						if (System.currentTimeMillis() - mClient.lastActive >= this.delay) {
							try {
								mClient.send("");
								LogUtis.log("send active.......");
							} catch (Exception localException) {
							}
						}
					}
					try {
						Thread.sleep(this.delay);
					} catch (InterruptedException localInterruptedException1) {
					}
				} else {
					// 如果网络好的情况则重登陆
					if(null==App.mContext){
						App.mContext=getApplicationContext();
					}
					if (ApplicationUtils.netState(App.mContext)) {
						Log.d("rtclogin",
								"login:" + SubUtils.getUuid(App.mContext));
						MessageService.startService(App.mContext,
								SubUtils.getUuid(App.mContext));
						try {
							Thread.sleep(10000L);
						} catch (InterruptedException localInterruptedException) {
						}
					}
				}
			}
			// new ----------------------------
//			try {
//				Thread.sleep(15000L);
//			} catch (InterruptedException localInterruptedException) {
//			}
		}
	}

}
